package com.ruoyi.wechat.controller;

import cn.hutool.json.JSONUtil;
import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.config.WechatCustomerConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.tool.WxPayNotifyResponse;
import com.ruoyi.common.utils.wechat.WxChatPayCommonUtil;
import com.ruoyi.order.domain.OrderOperation;
import com.ruoyi.order.domain.WxVhiceodr;
import com.ruoyi.order.domain.dto.WxVhiceodrDto;
import com.ruoyi.order.domain.ex.OrderConstant;
import com.ruoyi.order.domain.ex.OrderException;
import com.ruoyi.order.domain.vo.WxVhiceodrVo;
import com.ruoyi.order.service.IWxVhiceodrService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/wechat/vehorder")
public class OrderController extends BaseController {
    @Autowired
    private IWxVhiceodrService wxVhiceodrService;
    @Autowired
    private WechatCustomerConfig wechatCustomerConfig;
    @Autowired
    private RedisCache redisCache;

    private final String ORDER_VER = "ORDER_VER";

    /**
     * 获取车辆详细信息
     */
    @PostMapping(value = "/addOrder")
    public AjaxResult getInfo(@RequestBody WxVhiceodrDto wxVhiceodr,HttpServletRequest request) {
        try {
            //String ipAddress = request.getHeader("X-Forwarded-For");
            String ipAddress = request.getHeader("X-Forwarded-For");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
            }
            wxVhiceodr.setIp(ipAddress);
            return success(wxVhiceodrService.generateOrder(wxVhiceodr));
        } catch (OrderException orderException) {
            if (orderException.getCode() == OrderConstant.ORDER_UNPAID) {
                return AjaxResult.warn(orderException.getMessage(), orderException.getData());
            }
            return error(orderException.getMessage());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @PostMapping(value = "/payOrder")
    public AjaxResult payOrder(@RequestBody WxVhiceodrDto wxVhiceodr, HttpServletRequest request) {
        try {
            String ipAddress = request.getHeader("X-Forwarded-For");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
            }
            wxVhiceodr.setIp(ipAddress);
            return success(wxVhiceodrService.payOrder(wxVhiceodr));
        } catch (OrderException orderException) {
            if (orderException.getCode() == OrderConstant.ORDER_UNPAID) {
                return AjaxResult.warn(orderException.getMessage(), orderException.getData());
            }
            return error(orderException.getMessage());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 获取车辆详细信息
     */
    @GetMapping(value = "/{orderNum}")
    public AjaxResult getInfo(@PathVariable("orderNum") String orderNum) {
        return success(wxVhiceodrService.selectWxVhiceodrByNum(orderNum));
    }

    /**
     * 查询车辆列表
     */
    @GetMapping("/list")
    public TableDataInfo list(@RequestParam("wid") String wid, @RequestParam(required = false, name = "status") String status) {
        startPage();
        List<WxVhiceodrVo> list = wxVhiceodrService.selectWechatOrderList(wid, status);
        return getDataTable(list);
    }

    @GetMapping("/refundMoney")
    @Anonymous
    public AjaxResult refund(WxVhiceodrDto wxVhiceodr)
    {
        return success(wxVhiceodrService.refundMoney(wxVhiceodr));
    }

    @GetMapping("/cancelOrder/{orderNum}")
    public AjaxResult cancelOrder(@PathVariable String orderNum) {
        WxVhiceodr wxVhiceodr= wxVhiceodrService.selectWxVhiceodrByNum(orderNum);
        // 记录订单修改状态
        wxVhiceodrService.recordOrder(wxVhiceodr,OrderOperation.CANCEL_ORDERS);
        wxVhiceodr.setStatus(OrderOperation.CANCEL_ORDERS);
        return success(wxVhiceodrService.updateWxVhiceodr(wxVhiceodr));
    }


    /**
     * 用户提前还车
     *
     * @param wxVhiceodr 订单实体
     * @return 影响行数
     */
    @PostMapping("/returnCar")
    public AjaxResult returnCarInAdvance(@RequestBody WxVhiceodr wxVhiceodr) {
        if (!wxVhiceodr.getStatus().equals(OrderOperation.USE_LOADING.getMakeFlag())) {
            return error("非法订单");
        }
        wxVhiceodrService.recordOrder(wxVhiceodr, OrderOperation.USE_EXPIRE);
        WxVhiceodr wxVhiceodr1 = new WxVhiceodr();
        wxVhiceodr1.setId(wxVhiceodr.getId());
        wxVhiceodr1.setStatus(OrderOperation.USE_EXPIRE);
        wxVhiceodr1.setEndTime(wxVhiceodr.getEndTime());
        return AjaxResult.success(wxVhiceodrService.updateWxVhiceodr(wxVhiceodr1));
    }


    /**
     * 支付回调（微信）
     *
     * @param xmlData  微信XML数据
     * @param orderId  订单编号
     * @return 返回支付结果
     */
    //@Log(title = "支付回调（微信）")
    @PostMapping("/notify-order-wx/{orderId}")
    @Anonymous
    public String notifyOrderWx(HttpServletRequest request, HttpServletResponse response,
                                @RequestBody String xmlData,
                                @PathVariable("orderId") String orderId) throws IOException {
        if(orderId == null){
            System.out.println("验签失败");
            response.getWriter().write("<xml><return_code><![CDATA[FAIL]]></return_code></xml>");
        }
        String resXml = "";
        try {

            //Map<String, Object> ResultMap = imsYzzcSunOrderService.WeChatPayCallback(xmlData, RuoYiConfig.getApiKey());
            Map<String, Object> ResultMap=WeChatPayCallback(xmlData, wechatCustomerConfig.getApiKey());
            Map<String, String> WxResultMapData = new HashMap<>();
            if (ResultMap.get("Verify").equals("YES")) {
                //验签成功
                System.out.println("验签成功");
                WxResultMapData = (Map<String, String>) ResultMap.get("data");
                System.out.println("WxResultMapData:" + JSONUtil.toJsonStr(WxResultMapData));
                // 生成地址
                wxVhiceodrService.paymentSuccessOrder(orderId);

                //OrderInfo orderInfo = orderInfoService.selectOrderInfoByOrderNo(WxResultMapData.get("out_trade_no"));
                System.out.println("通知微信验签成功");
                //自信业务逻辑处理
                //orderInfoService.notifyOrder(orderInfo,tenantId,orderId,typeId,WxResultMapData);
                resXml = String.valueOf(ResultMap.get("returnWeChat"));
            } else if (ResultMap.get("Verify").equals("NO")) {
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[" + WxResultMapData.get("err_code_des") + "]]></return_msg>" + "</xml> ";
            }
        }catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        }
        return WxPayNotifyResponse.success("成功");
    }


    public Map<String, Object> WeChatPayCallback(String xmlData, String apiKey) {
        Map<String, Object> ResultMap = new HashMap<String, Object>();
        //解析到微信返回过来的xml数据
        try {
            //xml转Map
            Map<String, String> WxResultMap = WXPayUtil.xmlToMap(xmlData);
            //验证签名
            boolean SignStatus = WXPayUtil.isSignatureValid(WxResultMap, apiKey);
            if (SignStatus) {
                //验证成功
                //要返回给微信的xml数据
                String returnWeChat = WxChatPayCommonUtil.setReturnXml("SUCCESS", "OK");
                ResultMap.put("Verify", "YES");
                ResultMap.put("returnWeChat", returnWeChat);
                ResultMap.put("data", WxResultMap);
            } else {
                //验证失败(表示可能接口被他人调用  需要留意)
                ResultMap.put("Verify", "NO");
                ResultMap.put("msg", "验签失败。");
            }
            return ResultMap;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Anonymous
    @GetMapping("/getRandomCode")
    public AjaxResult getRandomCode(@RequestParam("orderNum") String orderNum) {
        AjaxResult ajax = AjaxResult.success();
        String verCode = generateVerificationCode(6);
        redisCache.setCacheObject(ORDER_VER + verCode, orderNum.trim(), 10, TimeUnit.MINUTES);
        ajax.put("verCode", verCode);
        ajax.put("userId", orderNum);

        return ajax;
    }

    @Anonymous
    @GetMapping("/validateCode")
    public AjaxResult validateCode(@RequestParam("orderNum") String orderNum,@RequestParam("valCode")  String valCode) {
        AjaxResult ajax = AjaxResult.success();
        String verOrderNum = redisCache.getCacheObject(ORDER_VER + valCode);
        if (ObjectUtils.isEmpty(verOrderNum)) {
            return error("验证码无效或过期");
        }
        ajax.put("isValidate",verOrderNum.equals(orderNum.trim()) );
        return ajax;
    }



    // 生成指定长度的验证码的方法
    private static String generateVerificationCode(int codeLength) {
        // 定义验证码字符集
        String codeChars = "0123456789";
        // 使用StringBuilder来拼接验证码
        StringBuilder verificationCode = new StringBuilder();
        // 创建Random对象
        Random random = new Random();
        // 循环生成指定长度的验证码
        for (int i = 0; i < codeLength; i++) {
            // 从字符集中随机选择一个字符
            char randomChar = codeChars.charAt(random.nextInt(codeChars.length()));
            // 将选定的字符追加到验证码中
            verificationCode.append(randomChar);
        }

        // 返回生成的验证码字符串
        return verificationCode.toString();
    }

}
